package com.yuyunbo.es.restclient.util;

import com.yuyunbo.es.restclient.annotation.*;
import com.yuyunbo.es.restclient.constants.EsConstants;
import com.yuyunbo.es.restclient.query.EsRangeQuery;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.util.*;

/**
 * @Author: yuyunbo-1154363414@qq.com
 * @Date: 2019/7/11 10:30
 * @Description:
 */
public class AnnotationUtil {
    private static Logger log = LoggerFactory.getLogger(AnnotationUtil.class);


    public static <T> String getESIndexValue(T dataBean, boolean isPustData) {
        Class<? extends Object> dataBeanClass = dataBean.getClass();
        EsIndexKey annotation = dataBeanClass.getAnnotation(EsIndexKey.class);
        if (annotation != null) {
            String indexName = annotation.indexName();
            String typeName = annotation.typeName();
            boolean isMonth = annotation.isMonthIndex();
            String value;
            if (isMonth && isPustData) {
                value = getMonthKeyColumnValue(dataBean);
                if (StringUtils.isEmpty(value)) {
                    throw new EsException("月份维度索引,请在索引字段上添加EsMonthKey 注解,并且该字段值不能为空");
                }
            }
            return indexName + EsConstants.SPLIE_KEY + typeName + EsConstants.SPLIE_KEY + isMonth;
        }
        return EsConstants.EMPTY;
    }

    public static <T> String getESPKeyColumnValue(T dataBean) {
        Field[] fields = dataBean.getClass().getDeclaredFields();
        String value = EsConstants.EMPTY;
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                EsPKey column = field.getAnnotation(EsPKey.class);
                if (column != null) {
                    value = (String) field.get(dataBean);
                    break;
                }
            } catch (Exception e) {
                log.error("获取ES PKey主键对应,所属字段值异常", e);
                throw new EsException("获取ES PKey主键对应,所属字段值异常");
            }
        }
        return value;
    }

    public static <T> String getMonthKeyColumnValue(T dataBean) {
        Field[] fields = dataBean.getClass().getDeclaredFields();
        String value = EsConstants.EMPTY;
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                EsMonthKey column = field.getAnnotation(EsMonthKey.class);
                if (column != null) {
                    value = (String) field.get(dataBean);
                    break;
                }
            } catch (Exception e) {
                log.error("获取ES EsMonthKey,所属字段值异常", e);
                throw new EsException("获取ES EsMonthKey,所属字段值异常");
            }
        }
        return value;
    }

    public static <T> Map<String, String> getEsMatchColumnValue(T dataBean) {
        Field[] fields = dataBean.getClass().getDeclaredFields();
        Map<String, String> value = new HashMap<>();
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                EsMatchKey column = field.getAnnotation(EsMatchKey.class);
                if (column != null) {
                    value.put(column.matchKey(), (String) field.get(dataBean));
                }
            } catch (Exception e) {
                log.error("获取EsMatchKey 对应,所属字段值异常", e);
                throw new EsException("获取ES EsMatchKey,所属字段值异常");
            }
        }
        return value;
    }

    public static <T> Map<String, List<String>> getEsShouldColumnValue(T dataBean) {
        Field[] fields = dataBean.getClass().getDeclaredFields();
        Map<String, List<String>> value = new HashMap<>();
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                EsShouldKey column = field.getAnnotation(EsShouldKey.class);
                if (column != null) {
                    value.put(column.shouldKey(), (List<String>) field.get(dataBean));
                }
            } catch (Exception e) {
                log.error("EsShouldKey 对应,所属字段值异常", e);
                throw new EsException("获取ES EsShouldKey,所属字段值异常");
            }
        }
        return value;
    }

    public static <T> Map<String, List<String>> getEsTermsColumnValue(T dataBean) {
        Field[] fields = dataBean.getClass().getDeclaredFields();
        Map<String, List<String>> value = new HashMap<>();
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                EsTermsKey column = field.getAnnotation(EsTermsKey.class);
                if (column != null) {
                    value.put(column.termsKey(), (List<String>) field.get(dataBean));
                }
            } catch (Exception e) {
                log.error("获取EsTermsKey 对应,所属字段值异常", e);
                throw new EsException("获取ES EsTermsKey,所属字段值异常");
            }
        }
        return value;
    }

    public static <T> List<EsRangeQuery> getEsRangeColumnValue(T dataBean) {
        Field[] fields = dataBean.getClass().getDeclaredFields();
        List<EsRangeQuery> list = new ArrayList<>();
        for (Field field : fields) {
            field.setAccessible(true);
            try {
                EsRangeKey column = field.getAnnotation(EsRangeKey.class);
                if (column != null) {
                    Map<String, Map<String, String>> rangeMap = new HashMap<>();
                    String value = (String) field.get(dataBean);
                    if (StringUtils.isNotEmpty(value)) {
                        Map<String, String> valueMap = new HashMap<>();
                        valueMap.put(column.matchType(), value);
                        rangeMap.put(column.rangeKey(), valueMap);
                        EsRangeQuery esRangeQuery = new EsRangeQuery();
                        esRangeQuery.setRange(rangeMap);
                        list.add(esRangeQuery);
                    }
                }
            } catch (Exception e) {
                log.error("获取EsRangeKey 对应,所属字段值异常", e);
                throw new EsException("获取ES EsRangeKey,所属字段值异常");
            }
        }
        return list;
    }

    public static <T> Map<String, String> getEsSortColumnValue(T dataBean) {
        Field[] fields = dataBean.getClass().getFields();
        Map<String, String> sortMap = new LinkedHashMap<>();
        for (Field field : fields) {
            field.setAccessible(true);
            EsSortList column = field.getAnnotation(EsSortList.class);
            if (column != null) {
                try {
                    Map<String, String> sortList = (Map<String, String>) field.get(dataBean);
                    if (sortList != null) {
                        sortMap = sortList;
                    }
                } catch (Exception e) {
                    log.error("获取EsSortList 对应,所属字段值异常", e);
                    throw new EsException("获取ES EsSortList,所属字段值异常");
                }
            }
        }
        if (sortMap.isEmpty()) {
            fields = dataBean.getClass().getDeclaredFields();
            for (Field field : fields) {
                field.setAccessible(true);
                EsSortKey column = field.getAnnotation(EsSortKey.class);
                if (column != null) {
                    sortMap.put(column.sortKey(), column.orderType());
                }
            }
        }
        return sortMap;
    }
}
